package top.java.commonClass;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;

/**
 *  说明： java中的对象，正常情况下，只能进行 == 或 != ，不能使用 > 或 < 的
 *        但是在开发中，我们需要对多个对象进行排序，即比较对象的大小
 *
 *           自然排序：java.lang.Comparable
 *           定制排序：java.util.Comparator
 *
 *          Comparable      与     Comparator    比较？
 *        实现接口后一直可以使用        临时性
 */

public class CompareTest1 {

    /**
     *      Comparable的使用：          自然排序
     *
     *      像String,包装类等实现了Comparable接口，重写了CompareTo()方法，给出了比较两个对象大小的方式
     *
     *      重写CompareTo()方法的规则：
     *          如果当前对象this大于形参对象obj，则返回正整数，
     *          如果当前对象this小于形参对象obj，则返回负整数，
     *          如果当前对象this等于形参对象obj，则返回零。
     *
     *      对于自定义类，如需要排序，我们可以让自定义类实现Comparable接口，重写CompareTo()方法
     *      在CompareTo()方法中指明如何排序
     *
     *      未重写Comparable接口的CompareTo()方法直接对自定义对象排序会报ClassCastException异常
     *      //Commodity cannot be cast to java.lang.Comparable
     *
     */
    @Test
    public void test1() {
        String[] str = new String[]{"QQ","WW","EE","RR","TT","YY","UU"};
        Arrays.sort(str);
        System.out.println(Arrays.toString(str));

        Commodity[] commodities = new Commodity[6];
        commodities[0] = new Commodity("111", 58);
        commodities[1] = new Commodity("222", 28);
        commodities[2] = new Commodity("333", 77);
        commodities[3] = new Commodity("444", 15);
        commodities[4] = new Commodity("555", 58);
        commodities[5] = new Commodity("666", 58);
        Arrays.sort(commodities);
        System.out.println(Arrays.toString(commodities));
    }

    /**
     *      Comparator的使用              定制排序
     *
     *      背景：
     *              当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码，
     *          或者实现了java.lang.Comparable接口的排序规则不适合当前的操作，那
     *          么可以考虑使用 Comparator 的对象来排序
     *
     *      重写规则：
     *              重写compare(Object o1,Object o2)方法，比较o1和o2的大小：如果方法返
     *          回正整数，则表示o1大于o2；如果返回0，表示相等；返回负整数，表示
     *          o1小于o2。
     */
    @Test
    public void test2() {

        String[] str = new String[]{"QQ","WW","EE","RR","TT","YY","UU"};
        Arrays.sort(str, new Comparator<String>() {
            //按照字符串从大到小进行排序
            @Override
            public int compare(String o1, String o2) {
                if (o1 instanceof String && o2 instanceof String) {
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                //    return s1.compareTo(s2);            //从小到大
                    return -s1.compareTo(s2);            //从大到小
                }
                throw new RuntimeException("传入数据的类型不一致");
            }
        });
        System.out.println(Arrays.toString(str));
    }

    /**
     *      自定义类实现Comparator
     */
    @Test
    public void test3() {
        Good[] good = new Good[6];
        good[0] = new Good("111", 58);
        good[1] = new Good("222", 28);
        good[2] = new Good("333", 77);
        good[3] = new Good("333", 15);
        good[4] = new Good("555", 58);
        good[5] = new Good("222", 58);

        Arrays.sort(good, new Comparator<Good>() {
            //产品名称从低到高，再按照价格从高到低
            @Override
            public int compare(Good o1, Good o2) {
                if (o1 instanceof Good && o2 instanceof Good) {
                    Good g1 = (Good) o1;
                    Good g2 = (Good) o2;
                    if (g1.getName().equals(g2.getName())) {
                        return -Double.compare(g1.getPrice(),g2.getPrice());
                    }else {
                        return g1.getName().compareTo(g2.getName());
                    }
                }
                throw new RuntimeException("传入数据的类型不一致");
            }
        });
        System.out.println(Arrays.toString(good));
    }

}



/**
 *      商品类
 */
class Commodity implements Comparable{

    private String name;
    private double price;

    public Commodity() {
    }

    public Commodity(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Commodity{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    //按价格从低往高排序
    @Override
    public int compareTo(Object o) {
        if (o instanceof Commodity) {
            Commodity commodity = (Commodity) o;
            if (commodity.price > this.price) {
                return -1;
            }else if(commodity.price < this.price) {
                return 1;
            }else {
                //return 0;
                //再按照产品名称从低到高排序
                return this.name.compareTo(commodity.name);
            }
        }
        throw new RuntimeException("传入的数据类型不一致");
    }
}

/**
 *      商品类
 */
class Good {

    private String name;
    private double price;

    public Good() {
    }

    public Good(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Good{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

}
